package com.smart.cosstarter.config;

import com.smart.cosstarter.constance.DefaultBuckets;
import com.smart.cosstarter.exception.AuthTokenNotFoundException;
import com.smart.cosstarter.exception.NoConfigException;
import com.cue.es.oss.model.*;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.BasicSessionCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.region.Region;
import com.smart.cosstarter.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.nio.charset.StandardCharsets;


/**
 * @Author: jj
 * @Date: 2019/8/21 11:34
 * @Version 1.0
 */
@Configuration
@EnableConfigurationProperties({ServiceProperties.class, ConfigProperties.class, DefaultBucket.class})
public class BeanInitAutoConfigure{

	@Autowired
	private ServiceProperties serviceProperties;

	@Autowired
	private ConfigProperties configProperties;

	@Autowired
	private DefaultBucket bucketProperties;

	@Bean
	@ConditionalOnMissingBean
	public AuthToken authToken() {
		COSAuthToken authToken = new COSAuthToken();
		authToken.setAppId(serviceProperties.getAppId());
		authToken.setSecretId(serviceProperties.getSecretId());
		authToken.setSecretKey(serviceProperties.getSecretKey());
		authToken.setRegion(serviceProperties.getRegion());
		return authToken;
	}

	@Bean
	@ConditionalOnMissingBean
	public COSClientConfig cosClientConfig() {
		COSClientConfig cosClientConfig = new COSClientConfig();
		cosClientConfig.setConnectionTimeout(configProperties.getConnectionTimeout());
		cosClientConfig.setHttpProtocol(configProperties.getHttpProtocol());
		cosClientConfig.setHttpProxyIp(configProperties.getHttpProxyIp());
		cosClientConfig.setHttpProxyPort(configProperties.getHttpProxyPort());
		cosClientConfig.setSignExpired(configProperties.getSignExpired());
		cosClientConfig.setSocketTimeout(configProperties.getSocketTimeout());
		return cosClientConfig;
	}

	@Bean
	@ConditionalOnMissingBean
	@ConditionalOnBean({AuthToken.class,COSClientConfig.class})
	public COSClient cosClient(AuthToken authTokenFactory, COSClientConfig cosClientConfigFactory) {
		COSClient cosClient;
		COSCredentials cred;
		String region = "";
		if (authTokenFactory instanceof COSAuthToken) {
			if (
					((COSAuthToken) authTokenFactory).getRegion() == null &&
					((COSAuthToken) authTokenFactory).getSecretId() == null &&
					((COSAuthToken) authTokenFactory).getSecretKey() == null){
				throw new AuthTokenNotFoundException();
			}
			// 1 初始化用户身份信息（secretId, secretKey）。
			if (((COSAuthToken) authTokenFactory).getAppId() != null && !"".equals(((COSAuthToken) authTokenFactory).getAppId())){
				cred = new BasicCOSCredentials(
						((COSAuthToken) authTokenFactory).getAppId(),
						((COSAuthToken) authTokenFactory).getSecretId(),
						((COSAuthToken) authTokenFactory).getSecretKey());
			}else {
				cred = new BasicCOSCredentials(
						((COSAuthToken) authTokenFactory).getSecretId(),
						((COSAuthToken) authTokenFactory).getSecretKey());
			}
			region = ((COSAuthToken) authTokenFactory).getRegion();
		} else if (authTokenFactory instanceof COSTempAuthToken) {
			if (
					((COSTempAuthToken) authTokenFactory).getRegion() == null &&
					((COSTempAuthToken) authTokenFactory).getTmpSecretId() == null &&
					((COSTempAuthToken) authTokenFactory).getTmpSecretKey() == null){
				throw new AuthTokenNotFoundException();
			}
			// 1 传入获取到的临时密钥 (tmpSecretId, tmpSecretKey, sessionToken)
			if (((COSTempAuthToken) authTokenFactory).getAppId() != null && !"".equals(((COSTempAuthToken) authTokenFactory).getAppId())){
				cred = new BasicSessionCredentials(
						((COSTempAuthToken) authTokenFactory).getAppId(),
						((COSTempAuthToken) authTokenFactory).getTmpSecretId(),
						((COSTempAuthToken) authTokenFactory).getTmpSecretKey(),
						((COSTempAuthToken) authTokenFactory).getSessionToken());
			}else {
				cred = new BasicSessionCredentials(
						((COSTempAuthToken) authTokenFactory).getTmpSecretId(),
						((COSTempAuthToken) authTokenFactory).getTmpSecretKey(),
						((COSTempAuthToken) authTokenFactory).getSessionToken());
			}
			region = ((COSTempAuthToken) authTokenFactory).getRegion();
		} else {
			throw new NoConfigException();
		}
		// 2 设置 bucket 的区域, COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
		// clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。
		ClientConfig clientConfig = new ClientConfig();
		if (cosClientConfigFactory != null &&
				(cosClientConfigFactory.getRegion() != null ||
						cosClientConfigFactory.getHttpProtocol() != null ||
						cosClientConfigFactory.getSignExpired() != null ||
						cosClientConfigFactory.getConnectionTimeout() != null ||
						cosClientConfigFactory.getSocketTimeout() != null ||
						cosClientConfigFactory.getHttpProxyIp() != null ||
						cosClientConfigFactory.getHttpProxyPort() != null)) {
			if (cosClientConfigFactory.getRegion() != null && !"".equals(cosClientConfigFactory.getRegion())) {
				clientConfig.setRegion(new Region(cosClientConfigFactory.getRegion()));
			}
			if (cosClientConfigFactory.getHttpProtocol() != null && !"".equals(cosClientConfigFactory.getHttpProtocol())) {
				clientConfig.setHttpProtocol(cosClientConfigFactory.getHttpProtocol());
			}
			if (cosClientConfigFactory.getSignExpired() != null && !"".equals(cosClientConfigFactory.getSignExpired())) {
				clientConfig.setSignExpired(cosClientConfigFactory.getSignExpired());
			}
			if (cosClientConfigFactory.getConnectionTimeout() != null && !"".equals(cosClientConfigFactory.getConnectionTimeout())) {
				clientConfig.setConnectionTimeout(cosClientConfigFactory.getConnectionTimeout());
			}
			if (cosClientConfigFactory.getSocketTimeout() != null && !"".equals(cosClientConfigFactory.getSocketTimeout())) {
				clientConfig.setSocketTimeout(cosClientConfigFactory.getSocketTimeout());
			}
			if (cosClientConfigFactory.getHttpProxyIp() != null && !"".equals(cosClientConfigFactory.getHttpProxyIp())) {
				clientConfig.setHttpProxyIp(cosClientConfigFactory.getHttpProxyIp());
			}
			if (cosClientConfigFactory.getHttpProxyPort() != null && !"".equals(cosClientConfigFactory.getHttpProxyPort())) {
				clientConfig.setHttpProxyPort(cosClientConfigFactory.getHttpProxyPort());
			}
		} else {
			Region regions = new Region(region);
			clientConfig.setRegion(regions);
		}
		// 3 生成 cos 客户端。
		cosClient = new COSClient(cred, clientConfig);
		if (bucketProperties.getBucket() != null && !"".equals(bucketProperties.getBucket())) {
			DefaultBuckets.bucket = bucketProperties.getBucket();
		}
		if (bucketProperties.getBaseDir() != null && !"".equals(bucketProperties.getBaseDir())) {
			DefaultBuckets.baseDir = new String(bucketProperties.getBaseDir().getBytes(), StandardCharsets.UTF_8);
		}
		return cosClient;
	}


	@Bean
	@ConditionalOnMissingBean
	@ConditionalOnBean(COSClient.class)
	@ConditionalOnClass(COSBucketsManager.class)
	public COSBucketsManager cosBucketsManager(COSClient cosClient) {
		return new COSBucketsManager(cosClient);
	}


	@Bean
	@ConditionalOnMissingBean
	@ConditionalOnBean(COSClient.class)
	@ConditionalOnClass(COSObjectManager.class)
	public COSObjectManager cosObjectManager(COSClient cosClient) {
		return new COSObjectManager(cosClient);
	}
}
